package es.xpt.ysf.commons.jaas.view;

import java.io.IOException;
import java.util.List;
import java.util.StringTokenizer;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

import es.xpt.ysf.YSFException;
import es.xpt.ysf.jaas.RoleBasedAuthorizationInterceptor;
import es.xpt.ysf.jaas.model.PrivilegesDigester;
import es.xpt.ysf.logging.LogManager;
import es.xpt.ysf.model.Item;
import es.xpt.ysf.view.Controller;
import es.xpt.ysf.web.Constants;

@SuppressWarnings("serial")
public class RolesController extends Controller { // NO_UCD
	
	private Item role = new Item();
	private List<Item> rolesList;
	private String tree;
	
	private RolesHelper helper = new RolesHelper();
	
	
	public RolesController () {
		super();
	}
	
	   public List<Item> getRolesList() {
	       if (rolesList == null)
	           try {
	               JaasDelegate d = new JaasDelegate(getUserBean());
	               rolesList = d.getRoles();
	           } catch (YSFException e) {
	               LogManager.getLog(getClass()).error(e.getMessage(), e);
	               setErrorMessage(e.getMessage());
	           }
	       return rolesList;
	   }
	
	
	   public String addRole() {
	       try {
	           JaasDelegate d = new JaasDelegate(getUserBean());
	           
	           d.insertRole(role);
	           setInfoMessage("commons.role.create", role.getShortName());
	           rolesList = null;
	           return Constants.SUCCESS_OUTCOME.getValue();
	       } catch (YSFException e) {
	           LogManager.getLog(getClass()).error(e.getMessage(), e);
	           setErrorMessage(e);
	           return Constants.FAILURE_OUTCOME.getValue();
	       }
	   }
	   
	   public String updateRole() {
	       try {
	    	   
	           JaasDelegate d = new JaasDelegate(getUserBean());
	           d.updateRole(role);
	           setInfoMessage("commons.role.update", role.getShortName());
	           role = null;
	           helper.setEditMode(false);
	           return Constants.SUCCESS_OUTCOME.getValue();
	       } catch (YSFException e) {
	           LogManager.getLog(getClass()).error(e.getMessage(), e);
	           setErrorMessage(e);
	           return Constants.FAILURE_OUTCOME.getValue();
	       }
	   }

	   public String deleteRole() {
	       try {
	           JaasDelegate d = new JaasDelegate(getUserBean());
	           role = (Item) helper.getRow().getRowData();
	           d.deleteRole(role.getCode());
	           rolesList = null;
	           setInfoMessage("commons.role.remove", role.getShortName());
	           return Constants.SUCCESS_OUTCOME.getValue();
	       } catch (YSFException e) {
	           LogManager.getLog(getClass()).error(e.getMessage(), e);
	           setErrorMessage(e.getMessage());
	           return Constants.FAILURE_OUTCOME.getValue();
	       }
	   }
	   
	   
	   public String getTree() {
		   if ( tree == null ) 
		   try {
	           JaasDelegate d = new JaasDelegate(getUserBean());
	           PrivilegesDigester permisosHandler = new PrivilegesDigester();
				permisosHandler.decode(Thread.currentThread().getContextClassLoader().getResourceAsStream("/privileges.xml"));
	           tree = helper.createTree(permisosHandler.getPrivileges(), d.getRolePrivileges(role.getCode()), getUserBean().getLocale().toString());
	       } catch (Exception e) {
	           LogManager.getLog(getClass()).error(e.getMessage(), e);
	           setErrorMessage(e.getMessage());
	           return Constants.FAILURE_OUTCOME.getValue();
	       }
	       return tree;
		   
	   }
	   
	   public void addPrivilege() {
		   addRemovePrivileges(true);
		   
	   }
	   
	   public void removePrivilege() {
		   addRemovePrivileges(false);
	   }

	   private void addRemovePrivileges(boolean add) {
		   String privileges = super.getFacesContext().getExternalContext().getRequestParameterMap().get("privileges");
		   String role = super.getFacesContext().getExternalContext().getRequestParameterMap().get("role");
		   
		   
		   try {
	           JaasDelegate d = new JaasDelegate(getUserBean());
		    if (privileges !=null)  {
			      if (privileges.indexOf(",")==-1) {
			    	if ( add )
			    		d.insertPrivilege(role, privileges);
			    	else
			    		d.removePrivilege(role, privileges);
			      } else {
			        StringTokenizer st = new StringTokenizer(privileges,",");
			        String[] aux = new String[st.countTokens()];
			        int i=0;
			        while(st.hasMoreTokens())  {
			          aux[i++]=st.nextToken();
			        }
			        
			        if ( add ) {
			        	d.removePrivileges(role,aux);
			        	d.insertPrivileges(role, aux);
			        } else
			        	d.removePrivileges(role,aux);
			      }
			    }
		    	RoleBasedAuthorizationInterceptor.loadPrivilegeRole();
		    	writeResponse("OK");
		   } catch ( YSFException e ) {
			   writeResponse("KO");
			   LogManager.getLog(getClass()).error(e.getMessage(), e);
		   }
		   
	   }
	   
	   private void writeResponse(String text) {
	   		FacesContext context = getFacesContext();
	   		context.renderResponse();
	   		context.responseComplete();
           try {
            	HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
            	response.setContentType("text/plain");
            	response.getWriter().write(text);
            	response.flushBuffer();
             }
             catch (IOException e) {
           	  LogManager.getLog(getClass()).error(e.getMessage(), e);
             }
         }

	/**
	 * @return the role
	 */
	public Item getRole() {
		return role;
	}

	/**
	 * @param role the role to set
	 */
	public void setRole(Item role) {
		this.role = role;
	}

	/**
	 * @return the helper
	 */
	public RolesHelper getHelper() {
		return helper;
	}

	/**
	 * @param helper the helper to set
	 */
	public void setHelper(RolesHelper helper) {
		this.helper = helper;
	}

	/**
	 * @param rolesList the rolesList to set
	 */
	public void setRolesList(List<Item> rolesList) {
		this.rolesList = rolesList;
	}

	/**
	 * @param tree the tree to set
	 */
	public void setTree(String tree) {
		this.tree = tree;
	}
	
}
